-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] RestDocs, Test 환경설정 #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
📝 Walkthrough🎯 WalkthroughREST Docs 기반 API 문서 생성 인프라를 구축합니다. Asciidoctor 플러그인, Spring REST Docs 의존성을 추가하고, 테스트 스니펫 생성 디렉토리를 구성하며, 문서 생성 태스크를 부트 JAR 빌드에 연결합니다. 📋 Changes
🎯 코드 리뷰 예상 시간🎯 3 (중간) | ⏱️ ~20분 🐰 축하 시
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (7)
🧰 Additional context used📓 Path-based instructions (3)src/**⚙️ CodeRabbit configuration file
Files:
**/*.java📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*Test.java📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
🧠 Learnings (5)📚 Learning: 2026-01-03T02:21:30.968ZApplied to files:
📚 Learning: 2026-01-03T02:21:30.968ZApplied to files:
📚 Learning: 2026-01-03T02:22:12.643ZApplied to files:
📚 Learning: 2026-01-03T02:21:30.968ZApplied to files:
📚 Learning: 2026-01-03T02:22:12.643ZApplied to files:
🔇 Additional comments (6)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
build.gradle.ktssrc/docs/asciidoc/api/community/community.adocsrc/docs/asciidoc/index.adocsrc/main/resources/templates/request-fields.snippetsrc/main/resources/templates/response-fields.snippet
🧰 Additional context used
📓 Path-based instructions (1)
src/**
⚙️ CodeRabbit configuration file
src/**: 다음 항목들을 꼼꼼하게 검토해줘.
- 예외 처리
- 예외가 적절히 처리되었는지 확인해줘. (try-catch, throws, ExceptionAdvice)
- 공통 예외 처리 모듈(예: GlobalHandler, ApiResponse 등)을 잘 활용했는지 확인.
- RuntimeException을 남발하지 않고, 의미 있는 커스텀 예외를 사용하는지 검토.
- 예외 메시지에 민감 정보(DB 정보, 사용자 정보 등)가 노출되지 않게 했는지 점검.
- 코드 품질 & 가독성
- 메소드/클래스가 단일 책임 원칙(SRP)에 맞게 구성되어 있는지.
- 중복 코드가 있는 경우, 유틸/공통 컴포넌트로 추출 가능한지.
- 의미 있는 변수명과 메소드명을 사용했는지.
- 매직 넘버, 하드코딩된 값이 존재하는지 점검.
- 성능 및 효율성
- 불필요한 DB 쿼리 호출, N+1 문제 가능성이 있는지 확인.
- Stream, loop, recursion 사용 시 시간복잡도/메모리 효율성을 고려했는지.
- 캐시 적용 가능성이 있거나, 과도한 연산이 반복되는 구간이 있는지.
- 트랜잭션 관리
- @transactional이 필요한 메소드에 누락되지 않았는지.
- 읽기 전용 트랜잭션(readOnly = true)을 적절히 사용했는지.
- DB 일관성, 롤백 정책이 올바른지 검토.
- 입력 검증 및 보안
- @Valid, Bean Validation 등을 통한 입력값 검증이 되어 있는지.
- 비밀번호, 토큰 등 민감한 정보가 로깅되지 않는지.
- 테스트
- 단위 테스트가 충분히 작성되었는지, 핵심 로직의 검증이 누락되지 않았는지.
- Mocking을 통한 독립 테스트 구조를 유지했는지.
- 경계값 테스트, 예외 케이스 테스트가 포함되어 있는지.
- 구조 및 설계
- Controller, Service, Repository 등 계층 구조가 올바르게 나뉘어 있는지.
- DTO, Entity, Domain 객체 간 변환 로직이 명확하고 중복되지 않는지.
- Config 클래스에서 Bean 등록이 과도하거나 순환 참조 위험이 없는지.
Files:
src/main/resources/templates/request-fields.snippetsrc/main/resources/templates/response-fields.snippetsrc/docs/asciidoc/api/community/community.adocsrc/docs/asciidoc/index.adoc
🪛 detekt (1.23.8)
build.gradle.kts
[warning] 114-114: This empty block of code can be removed.
(detekt.empty-blocks.EmptyFunctionBlock)
[warning] 115-115: This empty block of code can be removed.
(detekt.empty-blocks.EmptyFunctionBlock)
[warning] 116-116: This empty block of code can be removed.
(detekt.empty-blocks.EmptyFunctionBlock)
🔇 Additional comments (5)
src/docs/asciidoc/index.adoc (1)
1-15: REST Docs 메인 인덱스 구성이 적절합니다.문서 구조와 설정이 표준 REST Docs 패턴을 따르고 있으며, snippets 경로 및 include 지시자가 올바르게 설정되어 있습니다.
src/main/resources/templates/response-fields.snippet (1)
1-14: Response fields 스니펫 템플릿이 올바르게 작성되었습니다.Mustache 템플릿 구문과 AsciiDoc 테이블 형식이 표준 REST Docs 규칙을 따르고 있습니다.
src/main/resources/templates/request-fields.snippet (1)
1-14: Request fields 스니펫 템플릿이 올바르게 작성되었습니다.Response fields 템플릿과 일관된 구조로 작성되어 있으며, REST Docs 표준을 준수합니다.
build.gradle.kts (2)
5-5: Asciidoctor 플러그인 및 REST Docs 의존성이 올바르게 추가되었습니다.Issue #16의 요구사항에 맞게 Asciidoctor 플러그인과 REST Docs 의존성이 적절히 구성되었습니다.
Also applies to: 23-23, 98-100
129-146: REST Docs 문서 생성 및 패키징 구성이 완벽합니다.Issue #16의 요구사항을 모두 충족하는 구성입니다:
- ✅ asciidoctor 태스크가 test 결과물(snippets)을 입력으로 사용
- ✅ index.adoc만 처리하도록 sources 필터링
- ✅ bootJar가 asciidoctor에 의존하며 생성된 문서를 static/docs에 패키징
- ✅ 태스크 의존성 체인: test → asciidoctor → bootJar
빌드 파이프라인이 올바르게 구성되어 있습니다.
| val snippetsDir = file("build/generated-snippets") | ||
|
|
||
| tasks.test { | ||
| outputs.dir(snippetsDir) | ||
|
|
||
| addTestListener(object : TestListener { | ||
| override fun beforeSuite(suite: TestDescriptor) {} | ||
| override fun afterSuite(suite: TestDescriptor, result: TestResult) {} | ||
| override fun beforeTest(testDescriptor: TestDescriptor) {} | ||
|
|
||
| override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) { | ||
| if (result.resultType == TestResult.ResultType.FAILURE) { | ||
| println("🔴 FAILED TEST: ${testDescriptor.displayName}") | ||
| println("======================================") | ||
| result.exception?.printStackTrace() | ||
| println("======================================") | ||
| } | ||
| } | ||
| }) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
테스트 실패 시 상세 로그 출력 기능이 잘 구현되었습니다.
Issue #16의 요구사항대로 테스트 실패 시 상세한 로그를 출력하도록 구성되어 있습니다. 다만, 정적 분석 도구(detekt)에서 빈 블록(lines 114-116)에 대한 경고가 발생하고 있습니다.
🔎 정적 분석 경고 억제 방법
TestListener 인터페이스의 사용하지 않는 메서드들은 의도적으로 비워둔 것이므로, 다음과 같이 명시적으로 표시할 수 있습니다:
addTestListener(object : TestListener {
- override fun beforeSuite(suite: TestDescriptor) {}
- override fun afterSuite(suite: TestDescriptor, result: TestResult) {}
- override fun beforeTest(testDescriptor: TestDescriptor) {}
+ override fun beforeSuite(suite: TestDescriptor) { /* no-op */ }
+ override fun afterSuite(suite: TestDescriptor, result: TestResult) { /* no-op */ }
+ override fun beforeTest(testDescriptor: TestDescriptor) { /* no-op */ }
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {또는 detekt 설정에서 EmptyFunctionBlock 규칙을 조정할 수도 있습니다.
🧰 Tools
🪛 detekt (1.23.8)
[warning] 114-114: This empty block of code can be removed.
(detekt.empty-blocks.EmptyFunctionBlock)
[warning] 115-115: This empty block of code can be removed.
(detekt.empty-blocks.EmptyFunctionBlock)
[warning] 116-116: This empty block of code can be removed.
(detekt.empty-blocks.EmptyFunctionBlock)
🤖 Prompt for AI Agents
In build.gradle.kts around lines 108 to 127, detekt flags the empty overrides
for beforeSuite and beforeTest (lines 114-116) as problematic; replace their
empty block bodies with explicit no-op expressions (e.g., "override fun
beforeSuite(suite: TestDescriptor) = Unit" and "override fun
beforeTest(testDescriptor: TestDescriptor) = Unit") or add a targeted
suppression annotation/comment (e.g., @Suppress("EmptyFunctionBlock") on the
anonymous object or a brief "// no-op" comment inside each method) so the intent
is explicit and the static analysis warning is suppressed.
| [[community-post-create]] | ||
| === 커뮤니티 게시글 생성 | ||
|
|
||
| operation::subscription-controller-test/신규_구독을_등록한다[snippets='http-request,request-fields,http-response,response-fields'] No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
문서 제목과 operation 참조가 불일치합니다.
라인 2의 섹션 제목은 "커뮤니티 게시글 생성"인데, 라인 4에서 참조하는 operation은 "subscription-controller-test/신규_구독을_등록한다"(구독 생성)입니다. 이는 복사-붙여넣기 오류로 보이며, 문서 생성 시 잘못된 내용이 표시되거나 빌드가 실패할 수 있습니다.
올바른 커뮤니티 게시글 생성 테스트의 operation 이름으로 수정해주세요.
🔎 예상되는 수정 방향
-operation::subscription-controller-test/신규_구독을_등록한다[snippets='http-request,request-fields,http-response,response-fields']
+operation::community-controller-test/커뮤니티_게시글을_생성한다[snippets='http-request,request-fields,http-response,response-fields']정확한 테스트 메서드명은 실제 작성된 컨트롤러 테스트 코드를 확인해주세요.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/docs/asciidoc/api/community/community.adoc around line 4, the operation
reference points to subscription-controller-test/신규_구독을_등록한다 which does not
match the document title "커뮤니티 게시글 생성"; update the operation identifier to the
actual community-post creation test method name (e.g., the test class/method
under the community controller tests) so the snippet reference matches the
document. Locate the controller test that implements the "커뮤니티 게시글 생성" scenario,
copy its exact operation path/name, and replace the
subscription-controller-test/... token with that exact operation identifier
while leaving the
snippets='http-request,request-fields,http-response,response-fields' part
unchanged.
kyeoungwoon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P5: temp dir에 예시 test code와 함께 controller 하나 추가해주시면 좋을 것 같긴 해요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (6)
src/docs/asciidoc/index.adocsrc/test/java/com/umc/product/support/DocumentationTest.javasrc/test/java/com/umc/product/support/RestDocsConfig.javasrc/test/java/com/umc/product/support/UseCaseTestSupport.javasrc/test/resources/org/springframework/restdocs/templates/request-fields.snippetsrc/test/resources/org/springframework/restdocs/templates/response-fields.snippet
🧰 Additional context used
📓 Path-based instructions (3)
src/**
⚙️ CodeRabbit configuration file
src/**: 다음 항목들을 꼼꼼하게 검토해줘.
- 예외 처리
- 예외가 적절히 처리되었는지 확인해줘. (try-catch, throws, ExceptionAdvice)
- 공통 예외 처리 모듈(예: GlobalHandler, ApiResponse 등)을 잘 활용했는지 확인.
- RuntimeException을 남발하지 않고, 의미 있는 커스텀 예외를 사용하는지 검토.
- 예외 메시지에 민감 정보(DB 정보, 사용자 정보 등)가 노출되지 않게 했는지 점검.
- 코드 품질 & 가독성
- 메소드/클래스가 단일 책임 원칙(SRP)에 맞게 구성되어 있는지.
- 중복 코드가 있는 경우, 유틸/공통 컴포넌트로 추출 가능한지.
- 의미 있는 변수명과 메소드명을 사용했는지.
- 매직 넘버, 하드코딩된 값이 존재하는지 점검.
- 성능 및 효율성
- 불필요한 DB 쿼리 호출, N+1 문제 가능성이 있는지 확인.
- Stream, loop, recursion 사용 시 시간복잡도/메모리 효율성을 고려했는지.
- 캐시 적용 가능성이 있거나, 과도한 연산이 반복되는 구간이 있는지.
- 트랜잭션 관리
- @transactional이 필요한 메소드에 누락되지 않았는지.
- 읽기 전용 트랜잭션(readOnly = true)을 적절히 사용했는지.
- DB 일관성, 롤백 정책이 올바른지 검토.
- 입력 검증 및 보안
- @Valid, Bean Validation 등을 통한 입력값 검증이 되어 있는지.
- 비밀번호, 토큰 등 민감한 정보가 로깅되지 않는지.
- 테스트
- 단위 테스트가 충분히 작성되었는지, 핵심 로직의 검증이 누락되지 않았는지.
- Mocking을 통한 독립 테스트 구조를 유지했는지.
- 경계값 테스트, 예외 케이스 테스트가 포함되어 있는지.
- 구조 및 설계
- Controller, Service, Repository 등 계층 구조가 올바르게 나뉘어 있는지.
- DTO, Entity, Domain 객체 간 변환 로직이 명확하고 중복되지 않는지.
- Config 클래스에서 Bean 등록이 과도하거나 순환 참조 위험이 없는지.
Files:
src/test/resources/org/springframework/restdocs/templates/request-fields.snippetsrc/test/java/com/umc/product/support/UseCaseTestSupport.javasrc/test/java/com/umc/product/support/RestDocsConfig.javasrc/test/resources/org/springframework/restdocs/templates/response-fields.snippetsrc/docs/asciidoc/index.adocsrc/test/java/com/umc/product/support/DocumentationTest.java
**/*.java
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.java: Use camelCase naming convention for all method parameters and local variables
Use CONSTANT_CASE naming convention for public static final constants
Files:
src/test/java/com/umc/product/support/UseCaseTestSupport.javasrc/test/java/com/umc/product/support/RestDocsConfig.javasrc/test/java/com/umc/product/support/DocumentationTest.java
**/*Test.java
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*Test.java: Test method name should use descriptive Korean naming or BDD style naming (e.g.,챌린저_등록_성공()orshould_throw_exception_when_user_not_found()) instead of generic names liketest1()orregisterTest()
Test method should follow the Given-When-Then structure with clear comments separating each section (given, when, then)
Files:
src/test/java/com/umc/product/support/DocumentationTest.java
🧠 Learnings (3)
📚 Learning: 2026-01-03T02:21:30.968Z
Learnt from: CR
Repo: UMC-PRODUCT/umc-product-server PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-01-03T02:21:30.968Z
Learning: Applies to **/application/port/in/**UseCase.java : UseCase interface file should be named `{Action}{Domain}UseCase.java` following the pattern such as `RegisterChallengerUseCase.java`
Applied to files:
src/test/java/com/umc/product/support/UseCaseTestSupport.java
📚 Learning: 2026-01-03T02:22:12.643Z
Learnt from: CR
Repo: UMC-PRODUCT/umc-product-server PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T02:22:12.643Z
Learning: Applies to **/adapter/in/web/*Controller.java : Controller classes must depend only on UseCase interfaces, not on Service implementations directly
Applied to files:
src/test/java/com/umc/product/support/UseCaseTestSupport.java
📚 Learning: 2026-01-03T02:21:30.968Z
Learnt from: CR
Repo: UMC-PRODUCT/umc-product-server PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-01-03T02:21:30.968Z
Learning: Applies to **/adapter/in/**Controller.java : RestController should depend only on UseCase interfaces, not on Repository or other adapter implementations
Applied to files:
src/test/java/com/umc/product/support/UseCaseTestSupport.java
🔇 Additional comments (5)
src/test/resources/org/springframework/restdocs/templates/request-fields.snippet (1)
1-14: 템플릿 구조가 적절합니다.REST Docs의 request fields를 표현하기 위한 Mustache 템플릿이 올바르게 작성되었습니다. Path, Type, Optional, Description 컬럼 구조와 필드 반복 처리가 적절합니다.
src/docs/asciidoc/index.adoc (1)
1-11: 문서 구조가 적절합니다.REST API 문서를 위한 AsciiDoc 설정이 올바르게 구성되었습니다. snippets 경로와 문서 메타데이터(TOC, 하이라이팅 등)가 적절하게 설정되어 있습니다.
src/test/java/com/umc/product/support/DocumentationTest.java (1)
22-29: 필드 접근 제어자가 적절합니다.
protected접근 제어자를 사용하여 하위 테스트 클래스에서mockMvc,restDocsHandler,objectMapper에 접근할 수 있도록 설계되었습니다. 필드명도 camelCase 규칙을 준수하고 있습니다.src/test/resources/org/springframework/restdocs/templates/response-fields.snippet (1)
1-14: 템플릿 구조가 적절합니다.REST Docs의 response fields를 표현하기 위한 Mustache 템플릿이 올바르게 작성되었습니다. request-fields.snippet과 일관된 구조로 Path, Type, Optional, Description 컬럼을 정의하고 있습니다.
src/test/java/com/umc/product/support/RestDocsConfig.java (1)
10-11: 테스트 설정 클래스 구조 적절함
@TestConfiguration어노테이션과 클래스명이 적절하게 사용되었습니다. 테스트 전용 Bean 정의를 위한 올바른 구조입니다.
| @WebMvcTest( | ||
| ) | ||
| @Import({ | ||
| RestDocsConfig.class, | ||
| }) | ||
| @AutoConfigureMockMvc(addFilters = false) | ||
| @AutoConfigureRestDocs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# DocumentationTest를 extends하는 클래스들과 그들의 @WebMvcTest 설정 확인
rg -n "extends DocumentationTest" --type java -A 15 -B 2Repository: UMC-PRODUCT/umc-product-server
Length of output: 56
🏁 Script executed:
#!/bin/bash
# 1. DocumentationTest.java 파일 확인
echo "=== DocumentationTest.java 내용 ==="
find . -name "DocumentationTest.java" -type f | head -5
# 2. DocumentationTest를 import하거나 참조하는 파일들 검색
echo -e "\n=== DocumentationTest를 참조하는 파일들 ==="
rg "DocumentationTest" --type java
# 3. REST Docs 관련 @WebMvcTest 사용 패턴 확인
echo -e "\n=== @WebMvcTest 사용 패턴 ==="
rg "@WebMvcTest" --type java -A 3Repository: UMC-PRODUCT/umc-product-server
Length of output: 627
🏁 Script executed:
#!/bin/bash
# DocumentationTest.java 전체 내용 읽기
cat -n src/test/java/com/umc/product/support/DocumentationTest.javaRepository: UMC-PRODUCT/umc-product-server
Length of output: 1208
🏁 Script executed:
#!/bin/bash
# 1. RestDocsConfig 검색
echo "=== RestDocsConfig 파일 확인 ==="
find . -name "RestDocsConfig.java" -type java | head -5
# 2. RestDocumentationResultHandler 사용하는 클래스 찾기
echo -e "\n=== RestDocumentationResultHandler 참조 ==="
rg "RestDocumentationResultHandler" --type java -B 3 -A 3
# 3. REST Docs 관련 테스트 클래스들
echo -e "\n=== Test 클래스들 현황 ==="
fd ".*Test\.java$" src/test/java --type f | head -20Repository: UMC-PRODUCT/umc-product-server
Length of output: 3095
🏁 Script executed:
#!/bin/bash
# 1. 모든 Test 클래스 찾기 (고정된 find 명령)
echo "=== 모든 Test 클래스 ==="
find src/test/java -name "*Test.java" -type f
# 2. 더 광범위한 extends DocumentationTest 검색
echo -e "\n=== DocumentationTest 상속 여부 ==="
rg "extends\s+DocumentationTest|DocumentationTest\s*{" --type java -B 2 -A 8
# 3. @WebMvcTest 사용하는 모든 클래스
echo -e "\n=== @WebMvcTest 사용 클래스 ==="
rg "@WebMvcTest" --type java -B 5Repository: UMC-PRODUCT/umc-product-server
Length of output: 1032
🏁 Script executed:
#!/bin/bash
# @WebMvcTest()의 빈 controllers 파라미터 동작 확인
cat > /tmp/check_webmvctest.py << 'EOF'
# @WebMvcTest() with empty controllers parameter behavior
# According to Spring Boot documentation:
# - @WebMvcTest() with no controllers specified will load ALL controllers
# - This can cause issues because the context becomes too large
# - For a base class meant to be extended, this is suboptimal design
print("Spring Boot @WebMvcTest() behavior:")
print("1. @WebMvcTest() - loads ALL controllers in the application context")
print("2. @WebMvcTest(controllers = SpecificController.class) - loads ONLY specified controller")
print("\nFor a base class meant to be inherited:")
print("- Having @WebMvcTest() (all controllers) is problematic")
print("- Subclasses cannot override/narrow the controller scope")
print("- Better approach: Keep base class minimal, let subclasses specify controllers")
EOF
python /tmp/check_webmvctest.py
# 2. 실제 Spring Boot 권장사항 확인
echo -e "\n=== 결론 ==="
echo "DocumentationTest.java의 현재 상태:"
echo "- @WebMvcTest() 빈 파라미터 사용: 모든 컨트롤러 로드 (불필요)"
echo "- 아직 상속하는 클래스 없음: 현재 사용되지 않는 상태"Repository: UMC-PRODUCT/umc-product-server
Length of output: 160
REST Docs 테스트 기반 클래스 설정이 잘 구성되었습니다.
@WebMvcTest, @AutoConfigureRestDocs, addFilters = false 설정을 활용하여 문서화 테스트 기반 클래스를 효과적으로 구성했습니다. 다만, @WebMvcTest()에 컨트롤러를 지정하지 않으면 애플리케이션의 모든 컨트롤러를 로드하게 되어 문맥이 불필요하게 커집니다. 이 클래스를 상속하는 실제 테스트 클래스에서는 @WebMvcTest(controllers = YourController.class) 형태로 테스트할 컨트롤러를 명시하여 불필요한 빈 로드를 방지해야 합니다.
🤖 Prompt for AI Agents
In src/test/java/com/umc/product/support/DocumentationTest.java around lines 13
to 19, the base test class uses @WebMvcTest without specifying controllers which
causes all controllers to be loaded; update usage by ensuring subclasses that
extend this base test annotate themselves with @WebMvcTest(controllers =
YourController.class) (or controllers = {AController.class, BController.class})
to limit loaded beans and avoid unnecessary context size; keep the shared
annotations (@AutoConfigureMockMvc(addFilters = false), @AutoConfigureRestDocs,
@Import(RestDocsConfig.class)) in the base and only add the controllers
attribute on concrete test classes.
| import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation; | ||
| import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; | ||
|
|
||
| import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
와일드카드 static import 사용 검토 (선택적)
와일드카드 static import(import static ... Preprocessors.*;)를 사용하고 있습니다. REST Docs에서는 관례적으로 사용되는 패턴이지만, 명시적으로 필요한 메서드만 import하는 것이 더 명확할 수 있습니다.
🔎 명시적 import로 변경하는 제안
-import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;🤖 Prompt for AI Agents
In src/test/java/com/umc/product/support/RestDocsConfig.java around line 8,
replace the wildcard static import "import static
org.springframework.restdocs.operation.preprocess.Preprocessors.*;" with
explicit static imports for only the Preprocessors methods actually used in this
file (e.g., import static
org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
import static
org.springframework.restdocs.operation.preprocess.Preprocessors.removeHeaders;
etc.). Inspect the rest of the file to determine which static methods are
referenced, add explicit imports for those methods, and remove the wildcard
import to avoid importing unused members.
| @Bean | ||
| public RestDocumentationResultHandler restDocsMockMvcConfigurationCustomizer() { | ||
| return MockMvcRestDocumentation.document( | ||
| "{class-name}/{method-name}", | ||
| preprocessRequest(prettyPrint()), | ||
| preprocessResponse(prettyPrint()) | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
메서드명이 반환 타입과 불일치
메서드명 restDocsMockMvcConfigurationCustomizer()는 "Customizer"를 포함하지만, 실제로는 RestDocumentationResultHandler를 반환합니다. Spring REST Docs에서 "Customizer"는 일반적으로 RestDocsMockMvcConfigurationCustomizer 인터페이스를 구현하는 경우에 사용하는 용어입니다.
현재 코드는 Result Handler를 반환하므로 메서드명이 혼란을 야기할 수 있습니다. 메서드명을 반환 타입과 용도에 맞게 변경하는 것을 권장합니다.
🔎 메서드명 개선 제안
@Bean
-public RestDocumentationResultHandler restDocsMockMvcConfigurationCustomizer() {
+public RestDocumentationResultHandler restDocsHandler() {
return MockMvcRestDocumentation.document(
"{class-name}/{method-name}",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint())
);
}참고: 설정 내용 자체(문서 경로 패턴, pretty-print 전처리)는 REST Docs 표준 패턴을 잘 따르고 있으며 적절합니다.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @Bean | |
| public RestDocumentationResultHandler restDocsMockMvcConfigurationCustomizer() { | |
| return MockMvcRestDocumentation.document( | |
| "{class-name}/{method-name}", | |
| preprocessRequest(prettyPrint()), | |
| preprocessResponse(prettyPrint()) | |
| ); | |
| } | |
| @Bean | |
| public RestDocumentationResultHandler restDocsHandler() { | |
| return MockMvcRestDocumentation.document( | |
| "{class-name}/{method-name}", | |
| preprocessRequest(prettyPrint()), | |
| preprocessResponse(prettyPrint()) | |
| ); | |
| } |
🤖 Prompt for AI Agents
In src/test/java/com/umc/product/support/RestDocsConfig.java around lines 13 to
20, the bean method is named restDocsMockMvcConfigurationCustomizer() but
returns a RestDocumentationResultHandler which is misleading; rename the method
to reflect the return type and purpose (e.g., restDocumentationResultHandler or
restDocsResultHandler) and update any references/usages or @Autowired/bean
lookups that rely on the old method name so the bean name remains correct and
consistent with its role as a ResultHandler.
| @SpringBootTest | ||
| public abstract class UseCaseTestSupport { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find all test classes extending UseCaseTestSupport
rg -n "extends UseCaseTestSupport" --type java -C 10Repository: UMC-PRODUCT/umc-product-server
Length of output: 56
🏁 Script executed:
#!/bin/bash
# First, check if the file exists and read its contents
echo "=== Checking UseCaseTestSupport.java ==="
find . -name "UseCaseTestSupport.java" -type f
echo -e "\n=== Searching for test files that might extend it ==="
find ./src/test -name "*.java" -type f | head -20
echo -e "\n=== Looking for any references to UseCaseTestSupport ==="
rg "UseCaseTestSupport" --type javaRepository: UMC-PRODUCT/umc-product-server
Length of output: 647
🏁 Script executed:
#!/bin/bash
cat -n ./src/test/java/com/umc/product/support/UseCaseTestSupport.javaRepository: UMC-PRODUCT/umc-product-server
Length of output: 303
🏁 Script executed:
#!/bin/bash
echo "=== UmcProductApplicationTests.java ==="
cat -n ./src/test/java/com/umc/product/UmcProductApplicationTests.java
echo -e "\n=== DocumentationTest.java ==="
cat -n ./src/test/java/com/umc/product/support/DocumentationTest.java
echo -e "\n=== Checking for UseCase classes in src ==="
find ./src/main -name "*UseCase.java" -type f | head -10Repository: UMC-PRODUCT/umc-product-server
Length of output: 1628
🏁 Script executed:
#!/bin/bash
echo "=== Checking for any service/use case patterns in the project ==="
find ./src/main -name "*.java" -type f | grep -E "(Service|UseCase)" | head -10
echo -e "\n=== Checking application.yml or application.properties for context hints ==="
find ./src -name "application*.yml" -o -name "application*.properties"Repository: UMC-PRODUCT/umc-product-server
Length of output: 254
UseCaseTestSupport에서 @SpringBootTest 제거 필요
현재 이 클래스는 공유할 테스트 설정이나 유틸리티가 없는 빈 추상 클래스입니다. @SpringBootTest는 전체 애플리케이션 컨텍스트를 로드하므로 불필요합니다.
UseCase는 단일 책임 원칙을 따르는 단위 테스트 대상이므로, 다음 중 하나를 권장합니다:
@SpringBootTest제거 (상속 클래스에서 필요한 경우 개별 적용)- 또는 실제 공유 테스트 설정(예: 공통 Mock 설정, 테스트 데이터 초기화)을 추가한 후에만
@SpringBootTest사용
프로젝트의 DocumentationTest는 @WebMvcTest 같은 경량 슬라이스 테스트를 사용하고 있으므로, 이 기준에 맞추기를 권장합니다.
🤖 Prompt for AI Agents
In src/test/java/com/umc/product/support/UseCaseTestSupport.java around lines 6
to 7, the abstract test support class is annotated with @SpringBootTest but
provides no shared test configuration, causing unnecessary full application
context startup; remove the @SpringBootTest annotation from this base class so
subclasses can opt-in individually, or alternatively replace it by adding
meaningful shared test configuration (e.g., common @TestConfiguration, mocks, or
test data setup) and document that subclasses will inherit the slice only when
intended.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
build.gradle.kts
🔇 Additional comments (5)
build.gradle.kts (5)
23-23: 구현이 올바릅니다.
asciidoctorExt설정이 정확하게 생성되었으며, 의존성 선언(line 99)과 asciidoctor 태스크(line 117)에서 올바르게 사용되고 있습니다.
97-100: REST Docs 의존성이 올바르게 구성되었습니다.Issue #16의 요구사항에 따라 Spring REST Docs 의존성이 정확하게 추가되었습니다. Spring Boot의 의존성 관리를 활용하여 버전이 자동으로 관리되는 점도 적절합니다.
108-108: 스니펫 디렉토리가 올바르게 설정되었습니다.
build/generated-snippets는 Spring REST Docs의 표준 출력 디렉토리이며, 테스트 태스크와 asciidoctor 태스크 간의 연결이 적절하게 구성되었습니다.
115-125: Asciidoctor 태스크가 올바르게 구성되었습니다.Issue #16의 요구사항에 따라 문서 생성 태스크가 정확하게 구성되었습니다:
- 테스트로 생성된 스니펫을 입력으로 사용
index.adoc만 처리하도록 필터링test태스크에 대한 의존성 설정으로 올바른 실행 순서 보장
127-132: 빌드 태스크 의존성 체인이 올바르게 구성되었습니다.Issue #16의 요구사항에 따라
test → asciidoctor → bootJar체인이 정확하게 구성되었습니다. 생성된 문서가static/docs에 포함되어 애플리케이션 실행 시 접근 가능하도록 설정되었습니다.참고: Issue에서 언급된
copyDocument태스크는 별도로 생성되지 않았으며,bootJar태스크 내에서 인라인으로 복사가 수행됩니다. 이는 더 간결한 접근 방식입니다.
| java | ||
| id("org.springframework.boot") version "3.5.9" | ||
| id("io.spring.dependency-management") version "1.1.7" | ||
| id("org.asciidoctor.jvm.convert") version "4.0.5" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
org.asciidoctor.jvm.convert gradle plugin latest version 2025
💡 Result:
The latest release in 2025 is version 4.0.4 (released January 13, 2025). [1][2]
Sources:
- Maven Repository listing for org.asciidoctor.jvm.convert.gradle.plugin 4.0.4. [1]
- Gradle Plugin Portal (plugin page; shows earlier 4.0.2 example). [2]
🌐 Web query:
org.asciidoctor.jvm.convert 4.0.5 gradle plugin
💡 Result:
Short answer: There is no org.asciidoctor.jvm.convert plugin version 4.0.5 on the Gradle Plugin Portal — the latest published for that plugin id is 4.0.3 (published 20 Jul 2024). Other Asciidoctor JVM plugins (org.asciidoctor.jvm.base, .pdf, .gems, .js.convert, etc.) do have 4.0.5 releases. [1][2][3]
- org.asciidoctor.jvm.convert — latest listed: 4.0.3. [1]
- Example other plugin with 4.0.5: org.asciidoctor.jvm.base (4.0.5). [2]
- Asciidoctor Gradle plugin compatibility / docs. [3]
If you want, I can watch the Gradle Plugin Portal for a 4.0.5 release of org.asciidoctor.jvm.convert or suggest a migration path (use 4.x suite or the 1.5.x "org.asciidoctor.convert" legacy plugin).
플러그인 버전을 4.0.3으로 수정하세요.
org.asciidoctor.jvm.convert 버전 4.0.5는 존재하지 않습니다. Gradle Plugin Portal의 최신 버전은 4.0.3(2024년 7월 20일 발표)입니다. 현재 버전은 플러그인 해석 실패를 야기할 것입니다.
id("org.asciidoctor.jvm.convert") version "4.0.3"🤖 Prompt for AI Agents
In build.gradle.kts around line 5, the plugin declaration uses a non-existent
version "4.0.5"; change that version to "4.0.3" so the
id("org.asciidoctor.jvm.convert") line reads the supported plugin version and
the Gradle plugin resolution succeeds.
| tasks.test { | ||
| outputs.dir(snippetsDir) | ||
|
|
||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue #16의 테스트 실패 로그 요구사항이 누락되었습니다.
Issue #16에서는 "테스트 실패 시 상세 로그 출력 구성"을 명시적으로 요구하고 있습니다. 현재 코드는 outputs.dir(snippetsDir)만 설정되어 있어 기본 로그 레벨만 출력됩니다.
커밋 메시지("test task 간략화")를 보면 의도적인 간소화로 보이나, 이는 Issue 요구사항과 불일치합니다. 다음 중 하나를 선택하시기 바랍니다:
- Issue #16의 요구사항이 변경되었다면 이슈를 업데이트
- 테스트 실패 시 상세 로그 출력 기능을 다시 추가
🔎 테스트 실패 로그 출력 예시
이전 리뷰 댓글에서 언급된 것처럼 상세 로그 출력을 위해 다음과 같이 구성할 수 있습니다:
tasks.test {
outputs.dir(snippetsDir)
-
+
+ testLogging {
+ events("passed", "skipped", "failed")
+ showExceptions = true
+ showCauses = true
+ showStackTraces = true
+ exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
+ }
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| tasks.test { | |
| outputs.dir(snippetsDir) | |
| } | |
| tasks.test { | |
| outputs.dir(snippetsDir) | |
| testLogging { | |
| events("passed", "skipped", "failed") | |
| showExceptions = true | |
| showCauses = true | |
| showStackTraces = true | |
| exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL | |
| } | |
| } |
🤖 Prompt for AI Agents
In build.gradle.kts around lines 110-113 the test task only sets
outputs.dir(snippetsDir) but omits the detailed test-failure logging required by
Issue #16; restore explicit testLogging configuration on the tasks.test block to
emit detailed failure output (e.g., enable events for failed/skipped, set
exceptionFormat to FULL, and enable showing standard streams) while keeping
outputs.dir(snippetsDir), and update the commit message or Issue #16 if
requirements have changed.
kyeoungwoon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: commit message 컨벤션을 지켜서 다시 올려주세요!
kyeoungwoon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P5: 고생하셨습니다.
✅ 체크리스트
🔥 연관 이슈
🚀 작업 내용
💬 리뷰 중점사항
📃 관련 문서
Summary by CodeRabbit
릴리스 노트
새로운 기능
개선사항
테스트
✏️ Tip: You can customize this high-level summary in your review settings.